package com.gourd.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 集合工具类
 *
 * Created by 胡向南
 */
public class ListUtil {
    /**
     * 在list中匹配出值为value的项
     * @param list
     * @param value
     * @param <T>
     * @return
     */
    public static <T> T matchObject(List<T> list,T value) {
        if(list == null || list.size() == 0 || value == null){
            return null;
        }
        for(T t : list) {
            if(value.equals(t)){
                return t;
            }
        }
        return null;
    }
 
    /**
     * 在list中匹配出T中id属性值为id的项
     * @param list
     * @param id
     * @param <T>
     * @return
     */
    public static <T> T matchObject(List<T> list,Long id) {
        if(list == null || list.size() == 0 || id == null){
            return null;
        }
        Class clazz = list.get(0).getClass();
        Method method = null;
        try {
            method = clazz.getMethod("getId");
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        for(T t : list) {
            try {
                if(id.equals(method.invoke(t))){
                    return t;
                }
            } catch (IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
 
    /**
     * 在list中匹配出T中fieldName属性值为id的项
     * @param list
     * @param fieldName
     * @param id
     * @param <T>
     * @param <K>
     * @return
     */
    public static <T,K> T matchObject(List<T> list,String fieldName,K id) {
        if(list == null || list.size() == 0 || id == null){
            return null;
        }
        Class clazz = list.get(0).getClass();
        Method method = null;
        try {
            method = clazz.getMethod("get" +  upperFirstWord(fieldName));
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        for(T t : list) {
            try {
                if(id.equals(method.invoke(t))){
                    return t;
                }
            } catch (IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    /**
     * 在list中匹配出T中fieldName属性值在ids中的项
     * @param list
     * @param fieldName
     * @param ids
     * @param <T>
     * @param <K>
     * @return
     */
    public static <T,K> List<T> matchBatchObject(List<T> list,String fieldName,List<K> ids) {
 
        List<T> result = new ArrayList();
        if(list == null || list.size() == 0 || ids == null || ids.size() == 0){
            return result;
        }
        Class clazz = list.get(0).getClass();
        Method method = null;
        try {
            method = clazz.getMethod("get" +  upperFirstWord(fieldName));
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        for(K id :ids){
            for(T t : list) {
                try {
                    if(id.equals(method.invoke(t))){
                        result.add(t);
                        break;
                    }
                } catch (IllegalAccessException | InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
    /**
     * 在list中匹配出T中id属性值在ids中的项
     * @param list
     * @param ids
     * @param <T>
     * @return
     */
    public static <T> List<T> matchBatchObject(List<T> list,List<Long> ids) {
 
        List<T> result = new ArrayList();
        if(list == null || list.size() == 0 || ids == null || ids.size() == 0){
            return result;
        }
        Class clazz = list.get(0).getClass();
        Method method = null;
        try {
            method = clazz.getMethod("getId");
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        for(Long id :ids){
            for(T t : list) {
                try {
                    if(id.equals(method.invoke(t))){
                        result.add(t);
                        break;
                    }
                } catch (IllegalAccessException | InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
    /**
     * 在list中匹配出T中id属性值为id的集合
     * @param list
     * @param id
     * @param <T>
     * @return
     */
    public static <T> List<T> matchList(List<T> list,Long id) {
 
        List<T> result = new ArrayList();
        if(list == null || list.size() == 0 || id == null){
            return result;
        }
        Class clazz = list.get(0).getClass();
        Method method = null;
        try {
            method = clazz.getMethod("getId");
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
 
        for(T t : list) {
            try {
                if(id.equals(method.invoke(t))){
                    result.add(t);
                }
            } catch (IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
    /**
     * 在list中匹配出T中id属性值在ids中的集合
     * @param list
     * @param ids
     * @param <T>
     * @return
     */
    public static <T> List<T> matchList(List<T> list,List<Long> ids) {
 
        List<T> result = new ArrayList();
        if(list == null || list.size() == 0 || ids == null || ids.size() == 0){
            return result;
        }
        Class clazz = list.get(0).getClass();
        Method method = null;
        try {
            method = clazz.getMethod("getId");
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
 
        for(Long id : ids){
            for(T t : list) {
                try {
                    if(id.equals(method.invoke(t))){
                        result.add(t);
                    }
                } catch (IllegalAccessException | InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
 
        return result;
    }
    /**
     * 在list中匹配出T中fieldName属性值为id的集合
     * @param list
     * @param fieldName
     * @param id
     * @param <T>
     * @param <K>
     * @return
     */
    public static <T,K> List<T> matchList(List<T> list,String fieldName,K id) {
 
        List<T> result = new ArrayList();
        if(list == null || list.size() == 0 || id == null){
            return result;
        }
        Class clazz = list.get(0).getClass();
        Method method = null;
        try {
            method = clazz.getMethod("get" +  upperFirstWord(fieldName));
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
 
        for(T t : list) {
            try {
                if(id.equals(method.invoke(t))){
                    result.add(t);
                }
            } catch (IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
    /**
     * 在list中匹配出T中fieldName属性值在ids的集合
     * @param list
     * @param fieldName
     * @param ids
     * @param <T>
     * @param <K>
     * @return
     */
    public static <T,K> List<T> matchList(List<T> list,String fieldName,List<K> ids) {
 
        List<T> result = new ArrayList();
        if(list == null || list.size() == 0 || ids == null || ids.size() == 0){
            return result;
        }
        Class clazz = list.get(0).getClass();
        Method method = null;
        try {
            method = clazz.getMethod("get" +  upperFirstWord(fieldName));
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
 
        for(K id : ids){
            for(T t : list) {
                try {
                    if(id.equals(method.invoke(t))){
                        result.add(t);
                    }
                } catch (IllegalAccessException | InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
 
    /**
     * 获取list的id集合
     * @param list
     * @param <T>
     * @return
     */
    public static <T> List<Long> getKeyList(List<T> list) {
 
        List<Long> result = new ArrayList();
        if(list == null || list.size() == 0){
            return result;
        }
        Class clazz = list.get(0).getClass();
        Method method = null;
        try {
            method = clazz.getMethod("getId");
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
 
        Set<Long> set = new HashSet<>();
        for(T t : list) {
            try {
                Long id = (Long)method.invoke(t);
                if(id != null){
                    set.add(id);
                }
            } catch (IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        for(Long id : set){
            result.add(id);
        }
        return result;
    }
 
    /**
     * 获取list中fieldName属性值集合
     * @param list
     * @param fieldName
     * @param <T>
     * @param <K>
     * @return
     */
    public static <T,K> List<K> getKeyList(List<T> list,String fieldName) {
 
        List<K> result = new ArrayList();
        if(list == null || list.size() == 0){
            return result;
        }
        Class clazz = list.get(0).getClass();
        Method method = null;
        try {
            method = clazz.getMethod("get" +  upperFirstWord(fieldName));
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        Set<K> set = new HashSet<>();
 
        for(T t : list) {
            try {
                K k = (K)method.invoke(t);
                if(k != null){
                    set.add(k);
                }
            } catch (IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        for(K k : set){
            result.add(k);
        }
        return result;
    }
 
    /**
     * 将list中对象类型转换为T类型
     * @param list
     * @param clazz
     * @param <T>
     * @param <K>
     * @return
     */
    public static <T,K> List<T> transferBatch(List<K> list, Class<T> clazz){
        List<T> tList = new ArrayList<>();
 
        for(K k : list){
            T t = transfer(k,clazz);
            tList.add(t);
        }
        return tList;
    }
 
    /**
     * 首字符转大写
     * @param str
     * @return
     */
    public static String upperFirstWord(String str) {
        String temp = str.substring(0, 1);
        return temp.toUpperCase() + str.substring(1);
    }
 
    /**
     * 将对象转化为指定类型对象
     * @param object
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T transfer(Object object, Class<T> clazz) {
        JSONObject obj = JSON.parseObject(JSON.toJSONString(object));
        T t = JSON.toJavaObject(obj, clazz);
        return t;
    }
 
}